﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Com.Charence.PassManager.BusinessEntities;
using Com.Charence.PassManager.Common;
using Com.Charence.PassManager.Common.Messages;

namespace Com.Charence.PassManager.DataComponents
{
    public class AuthenticateDC
    {
        public void AddQRToken(string tokenString)
        {
            using (var context = new Entities())
            {
                var token = new QRToken
                {
                    Token = tokenString,
                    ExpireTime = DateTime.Now.AddMinutes(10.0),
                    IsUsed = false,
                    IsDeleted = false,
                    CreatedBy = "SYSTEM",
                    CreatedOn = DateTime.Now,
                    UpdatedBy = "SYSTEM",
                    UpdatedOn = DateTime.Now
                };
                context.QRTokens.Add(token);

                context.SaveChanges();
            }
        }

        public bool ConnentHub(string tokenString, string connectionId)
        {
            using (var context = new Entities())
            {
                var token = context.QRTokens.SingleOrDefault
                    (p => p.Token == tokenString && p.ExpireTime > DateTime.Now && !p.IsUsed && !p.IsDeleted);
                if (token == null) return false;
                token.ConnectionID = connectionId;
                token.UpdatedBy = "SignalR";
                token.UpdatedOn = DateTime.Now;

                context.SaveChanges();
                return true;
            }
        }

        public string TryQRLogin(string tokenString, string userName, string password)
        {
            using (var context = new Entities())
            {
                var token = context.QRTokens.SingleOrDefault
                    (p => p.Token == tokenString && p.ExpireTime > DateTime.Now && !p.IsUsed && !p.IsDeleted);
                if (token == null)
                    throw new LoginException(MessageManager.Current["Err-Login-001"]);

                var user = context.Users.SingleOrDefault(p => p.IsActive && p.UserAccount == userName);
                if (user == null)
                    throw new LoginException(MessageManager.Current["Msg-Login-003"]);

                if (user.Password == password)
                {
                    token.IsUsed = true;

                    user.FailedAttempts = 0;

                    context.QRScanRecords.Add(new QRScanRecord
                    {
                        UserID = user.UserID,
                        QRTokenID = token.ID,
                        IsUsed = false
                    });
                    context.SaveChanges();
                }
                else
                {
                    token.IsUsed = true;
                    user.FailedAttempts++;
                    context.SaveChanges();

                    throw new LoginException(MessageManager.Current["Msg-Login-004"]);
                }
                return token.ConnectionID;
            }
        }

        public int DoLogin(string tokenString, out string message)
        {
            using (var context = new Entities())
            {
                var result = from t in context.QRTokens
                             join m in context.QRScanRecords
                             on t.ID equals m.QRTokenID
                             where t.Token == tokenString
                              && !m.IsUsed
                             select m;
                if (result.Any())
                {
                    var record = result.Single();

                    message = "Login success";

                    context.QRScanRecords.First(p => p.ID == record.ID).IsUsed = true;
                    context.SaveChanges();

                    return record.UserID;
                }
                message = "Login Failed";
                return -1;
            }
        }

        public int DoLoginOnWeb(string userName, string password)
        {
            using (var context = new Entities())
            {
                var user = context.Users.SingleOrDefault(p => p.IsActive && p.UserAccount == userName);
                if (user == null)
                    throw new LoginException(MessageManager.Current["Msg-Login-003"]);

                if (user.Password == password)
                {
                    user.FailedAttempts = 0;
                    context.SaveChanges();

                    return user.UserID;
                }
                else
                {
                    user.FailedAttempts++;
                    context.SaveChanges();

                    throw new LoginException(MessageManager.Current["Msg-Login-004"]);
                }
            }
        }
    }
}
